Bingo, Computer Graphics & Game Developer

Compiler Compiler

专业课没有开编译原理,因此刚刚上手Flex+Bison的时候有很多概念性错误。这里不做教程,只是我个人在学习中的心得

基于Flex与Bison学习


2015.10.13备注

Chapter 1

  1. Flex在使用gcc编译时会用到一个名叫lfl的库,本质上是yywarp,大多数都会在声明部分启用%option noyywrap,一般不需要此库。


  2. Flex与Bison本质上是给定文法生成指定.c, .h文件提供给工程,因此本身的main主程序测试不是必须的。


  3. Flex本质是词法分析器,因此在分析到指定token时,会需要用到具体的tokenType。这一般会在Bison中指定,那么就会前向声明#include Bison生成的.h,例如xxx.tab.h.


  4. Bison与Flex使用的是标准C,因此当使用cc编译命令时//注释不可用,需为/ /


  5. Bison功用是根据BNF范式生成一颗AST树,这颗树很可能是不可见,也就是隐藏的。


  6. Flex的规则列表中切忌是不可以增加注释的,只能在右边的动作或者在规则开始声明符%%之前添加注释.且规则和动作之间至少增加一个空格,否则{}也会被认定为正则表达式。


2015.10.30备注

###Chapter 9

1.纯词法分析器和纯语法分析器协同工作。不仅是Flex上给出%option reentrant和%option bison-bridge+Bison %pure-parser那么简单(原本使用书上注明的%define api.pure在OSX上不可用,应该是版本问题,具体情况可以参考Webkit上的.flex)。
其中bison-bridge的作用就是完成Flex上与Bison上不协调的yylex()所做的对接。

// Flex
token = yylex(YYSTYPE *yylvalp);
// Bison
token = yylex(yyscan_t scaninfo);

之前自己在Flex中或Bison或具体外部使用之前的前向声明都可以隐藏,或手动声明为

int yylex(YYSTYPE *lvalp, yyscan_t scaninfo);

2.%parse-param/#define YYPARSE_PARAM%lex-param/#define YYLEX_PARAM都可以声明传递给分析器应用数据的类型,但根据版本迭代的情况而言,以及借鉴Webkit使用情况,推荐使用%parse-param%lex-param

3.强烈建议包含Flex+Bison生成的头文件时查看包含关系。因为一旦重复包含或少包含都会引起非常难以调试的符号未定义BUG,哪怕在生成的源文件中已经#define了此符号。

4.Bison在定义%token时,使用到了某单符号,例如’-‘’+’等等,此类token若未在Bison中给出相应名,那么就需要分配其指定类型。

5.BNF范式在实现中,务必手工生成一遍语法树,很有可能其 空 的部分顺序是错误的,因为Bison在面对二义性语法上会选择匹配长度更长的,或者是最新匹配的那一部分,因此 空 实现的顺序就尤为关键。

6.Flex+Bison支持简单的class内置,所有的中文资料显示2009年时两者未能有效支持C++,需要%language “C++”来完成对C++的支持,目前看来无需此关键字也能完成class对struct的替换。

7.Flex中yyextra指针分配给指定对象的声明位置尤为关键不在头部的%{ %}对中,而是在词法分析单元声明部分中。